﻿using System;
using System.Collections.Generic;
using System.IO;
using BitBenderGames;
using com.yoozoo.gta.Extension.UGUI.ScreenOrientationEx;
using com.youzu.warh.protocol;
using UnityEngine;
using UnityEngine.Networking;
using WorldMapBase;
using XLua;
using Yoozoo.Gameplay.RTS;
using Yoozoo.Gameplay.RTS.Proto;
using Yoozoo.Gta.Common;
using Yoozoo.Mars.Got;
using Yoozoo.Mars.Got.SpriteAnim;
using SCRoundFight = com.youzu.warh.protocol.SCRoundFight;

namespace Yoozoo.Gameplay.RTS
{
    public class RtsExpeditionManager
    {
        private static RtsExpeditionManager m_instance;
        
        private Dictionary<int,List<long>> marchList = new Dictionary<int,List<long>>();
        private bool start = false;

        private bool isReadyToEnd;
        private long readyToEndTime;

        private long startTime;

        public Camera MainCamera;
        private MobileTouchCamera MobileTouchCamera;
        
        public Vector3 CenterPosition = Vector3.zero;

        public static bool IsTimeDebug = false;

        public static RtsExpeditionManager Instance
        {
            get
            {
                if (m_instance == null)
                {
                    m_instance = new RtsExpeditionManager();
                    m_instance.Initialize();
                }
                return m_instance;
            }
        }

        public long playerId;
        
        public void SetPlayerId(long playerId)
        {
            this.playerId = playerId;
        }

        public void PreloadArenaInitConfig(LuaTable table,int type)
        {
            for (int i = 1; i <= table.Length; i++)
            {
                var config = table.Get<int, LuaTable>(i);
                if (config != null)
                {
                    int id = GetInt(config, "id");
                    float x = GetFloat(config, "x");
                    //float y = GetFloat(config, "y");
                    float z = GetFloat(config, "z");
                    MarchHelper.SetArenaInitPosition(id, x, z, type);
                }
            }
        }
        
        private int GetInt(LuaTable table, string key)
        {
            return table.ContainsKey(key) ? table.Get<string, int>(key) : 0;
        }

        private float GetFloat(LuaTable table, string key)
        {
            return table.ContainsKey(key) ? table.Get<string, float>(key) : 0;
        }

        public long GetServerTimeMs()
        {
            var deltaTick = (long)((Environment.TickCount - timeDebugStartClickTick) * timeScale);
            return deltaTick + timeDebugStartTime;
        }
        
        public long GetClientTimeMs()
        {
            var deltaTick = (long)((Environment.TickCount - timeDebugStartClickTick) * timeScale);
            return deltaTick;
        }

        private long timeDebugStartTime;
        private long timeDebugStartClickTick;
        private float timeScale = 1;
        
        public void SetTimeScale(float timeScale)
        {
            timeDebugStartTime = TimeUtils.GetServerTimeMs();
            timeDebugStartClickTick = Environment.TickCount;
            this.timeScale = timeScale;
            RtsArenaManager.IsTimeDebug = true;
        }
        
        
        public void Initialize()
        {
           
        }

        private Action testAction;
        
        public void Update()
        {
            if (testAction != null)
            {
                testAction.Invoke();
                testAction = null;
            }
        }

        public void AddTestAction(Action action)
        {
            testAction = action;
        }

        public void Start()
        {
            IsTimeDebug = false;
            timeScale = 1;
        }
        public void CreateBattleUnit(ArenaBattleTroop troop,int team)
        {
            ResidentHandler.Inst.GetFunction("L_RtsArenaManager.CreateArenaMarch").Action(new RtsArenaTroop{
                troop = troop,
            },team);
            if (!marchList.TryGetValue(team,out var teamList))
            {
                teamList = new List<long>();
                marchList.Add(team,teamList);
            }
            teamList.Add(troop.troopId);
        }

        public void CreateFormationUnit(int _troopId,int _heroId, int _position, int _soldierId,int _soldiderCount, int _team)
        {
            int troopId = _troopId;
            int heroId = _heroId;
            int position = _position;
            int soldierId = _soldierId;
            int team = _team;
            int soldiderCount = _soldiderCount;
            Timers.inst.CallLater((o) =>
            {
                ArenaBattleTroop troop = new ArenaBattleTroop();
                troop.troopId = troopId;
                troop.heroList.Add(new ArenaHero() { heroId = heroId });
                troop.initPos = position;
                troop.soldier = new IntPair()
                {
                    key = soldierId,
                    value = soldiderCount,
                };
                var troopData = new RtsArenaTroop
                {
                    troop = troop,
                };
                try
                {
                    ResidentHandler.Inst.GetFunction("L_RtsExpedition.CreateExpeditionMarch").Action(troopData, team,true);
                }
                catch (Exception e)
                {
                    Debug.LogError(e.ToString());
                }
      

                if (!marchList.TryGetValue(team, out var teamList))
                {
                    teamList = new List<long>();
                    marchList.Add(team, teamList);
                }
                teamList.Add(troop.troopId);
            });
        }

        public void Clear()
        {
            ResidentHandler.Inst.GetFunction("L_RtsArenaManager.Clear").Action();
        }

        public void Dispose()
        {
            UnApplyCamera();
            MarchManager.Instance?.UnsetArenaMarchContext();
            start = false;
            isReadyToEnd = false;
            MarchManager.Instance.IsInArena = false;
        }

        private Camera originCamera;
        
        public void SetCamera(Camera camera)
        {
            MainCamera = camera;
            MobileTouchCamera = MainCamera.GetComponent<MobileTouchCamera>();
            MarchManager.Instance?.SetArenaMarchContext(camera.transform);
            ApplyCamera();
        }

        public void LockCamera()
        {
            if (MobileTouchCamera!=null)
            {
                MobileTouchCamera.Locked = true;
            }
        }
            
        public void UnLockCamera()
        {
            if (MobileTouchCamera != null)
            {
                MobileTouchCamera.Locked = false;
            }
        }

        private void InitDrawLineTools()
        {
            // 画线工具
            DrawLineTool drawLineTool = DrawLineTool.GetInstance();
            if (!drawLineTool.IsInitialized())
            {
                drawLineTool.Initialize();
            }
            drawLineTool.SetHeight(GlobalValue.PathLineHeight);
            drawLineTool.SetFollowTarget(MainCamera.transform);
            drawLineTool.materialType = 0;
            drawLineTool.LINE_WIDTH = 0.08f;
        }

        private bool hasApplyCamera = false;

        private Camera worldCamera;
        private void ApplyCamera()
        {
            if (!hasApplyCamera)
            {
                InitDrawLineTools();
                hasApplyCamera = true;
                worldCamera = WorldCameraManager.mainCamera;
                var worldCameraManager = WorldCameraManager.GetInstance();
                if (worldCameraManager)
                {
                    worldCameraManager.SetCamera(MainCamera);
                }
                if (GpuHudFacade.GpuFacade != null)
                {
                    var hudCamera = MainCamera.transform.Find("HudCamera");
                    if (hudCamera != null)
                    {
                        GpuHudFacade.GpuFacade.m_hudCamera = hudCamera.gameObject.GetComponent<Camera>();
                    }
                }
            }
            if (ScreenOrientManager.GetInstance().IsPortrait())
            {
                ArmyManager.Instance.SetCameraRotation(135f);
            }
            else
            {
                ArmyManager.Instance.SetCameraRotation(45f);
            }
        }

        private void UnApplyCamera()
        {
            if (hasApplyCamera)
            {
                hasApplyCamera = false;
                var worldCameraManager = WorldCameraManager.GetInstance();
                if (worldCameraManager)
                {
                    worldCameraManager.SetCamera(worldCamera);
                }
                if (worldCamera != null)
                {
                    ArmyManager.Instance.InitDrawLineTools();
                }
                worldCamera = null;
                if (GpuHudFacade.GpuFacade != null)
                {
                    var hudCamera = WorldCameraManager.mainCamera.transform.Find("HudCamera");
                    if (hudCamera != null)
                    {
                        GpuHudFacade.GpuFacade.m_hudCamera = hudCamera.gameObject.GetComponent<Camera>();
                    }
                }
            }
            ArmyManager.Instance.SetCameraRotation(45f);
        }
    }
}
